package monash.med.crystallography.DatasetTools.MetsCreator;

import java.io.FileOutputStream;

import edu.harvard.hul.ois.mets.*;
import edu.harvard.hul.ois.mets.helper.MetsValidator;
import edu.harvard.hul.ois.mets.helper.MetsWriter;
import edu.harvard.hul.ois.mets.helper.PreformedXML;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * MetsCreator by Steve Androulakis - For creating Fedora-compatible METS XML data for object ingestion
 * <p>
 * Use static method joinFile(String label, String[] creators, String description, String source, String relation)
 * 
 * @author Steve Androulakis (Monash University)
 * @version 1.0
 */
public class MetsCreator {
	
	private static Mets mets;

	private static void CreateMETSObject(String label, String[] creators, String description, String source, String relation)
	{	
		String dublinCreators = "";
                String marcCreators = "";                
		
		for(String creator : creators)
		{
			dublinCreators = dublinCreators + "\n\t\t\t<dc:creator>" + creator.trim() + "</dc:creator>";
                        marcCreators = marcCreators +
"		\t\t<default:datafield ind1=\"1\" ind2=\" \" tag=\"700\">\n"+
"		    \t\t\t<default:subfield code=\"a\">"+ creator.trim() +"</default:subfield>\n"+
"		\t\t</default:datafield>\n";
		}
		
		mets = new Mets();
		
		mets.setLABEL(label);
		
		mets.setTYPE("FedoraObject");
		
		mets.setSchema("fedoraxsi", "http://www.loc.gov/METS/ http://www.fedora.info/definitions/1/0/mets-fedora-ext.xsd");
		
		MetsHdr metsHdr = new MetsHdr ();
		metsHdr.setRECORDSTATUS("I");
		
		mets.getContent().add(metsHdr);
		
		AmdSec amdSec = new AmdSec();
		amdSec.setID("DC");
		
			TechMD techMD = new TechMD();
			techMD.setID("DC.0");
		
					MdWrap mdWrap = new MdWrap();
					mdWrap.setLABEL("Default Dublin Core Record");
					mdWrap.setID("DCRecord");
					mdWrap.setMDTYPE(Mdtype.OTHER);
					mdWrap.setOTHERMDTYPE("UNSPECIFIED");
					mdWrap.setMIMETYPE("text/xml");
												
					    XmlData xmlData = new XmlData ();
					    /* Use the PreformedXML element */
                                                
                                            try {
                                            
					      PreformedXML preformed = new PreformedXML("" +
					    		"\n\t\t<oai_dc:dc xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:oai_dc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\">" +
					      		"\n\t\t\t<dc:title>" + label.trim() + "</dc:title>" +
						      		dublinCreators +
					      		"\n\t\t\t<dc:description>" + description.trim() + "</dc:description>" +
					      		"\n\t\t\t<dc:type>data holding</dc:type>" +
                                                        "\n\t\t\t<dc:type>crystal structure data holding</dc:type>" +
					      		"\n\t\t\t<dc:relation>" + URLEncoder.encode(relation.trim(), "UTF-8") + "</dc:relation>" +
					      		"\n\t\t</oai_dc:dc>\n\t" +
					      "");
                                              
                                              xmlData.getContent().add(preformed);
                                              
                                            }
                                            catch(UnsupportedEncodingException e)
                                            {
                                                System.out.println("Unsupported URL Encoding for Relation element");
                                            }
					      
					    
					mdWrap.getContent().add(xmlData);
			techMD.getContent().add(mdWrap);
		amdSec.getContent().add(techMD);
	mets.getContent().add(amdSec);
	
		AmdSec amdSecMARC = new AmdSec();
		amdSecMARC.setID("MARCDESC");
		
			TechMD techMDMARC = new TechMD();
			techMDMARC.setID("MARCDESC.0");
		
					MdWrap mdWrapMARC = new MdWrap();
					mdWrapMARC.setLABEL("MARCXML Record");
					mdWrapMARC.setID("MARCXMLRecord");
					mdWrapMARC.setMDTYPE(Mdtype.OTHER);
					mdWrapMARC.setOTHERMDTYPE("UNSPECIFIED");
					mdWrapMARC.setMIMETYPE("text/xml");
												
					    XmlData xmlDataMARC = new XmlData ();
					    /* Use the PreformedXML element */
                                            
                                            try{
					      PreformedXML preformedMARC = new PreformedXML("" +
"<default:collection xmlns:default=\"http://www.loc.gov/MARC21/slim\">\n"+
"	\t<default:record>\n"+
"		\t\t<default:leader>00000nam a22000002a 4500</default:leader>\n"+
"		\t\t<default:controlfield tag=\"008\">       19uu9999   |||||s|||||00| 0|eng d </default:controlfield>\n"+
                marcCreators +
"		\t\t<default:datafield ind1=\"0\" ind2=\"0\" tag=\"245\">\n"+
"			\t\t\t<default:subfield code=\"a\">"+ label.trim() +"</default:subfield>\n"+
"		\t\t</default:datafield>\n"+
"		\t\t<default:datafield ind1=\"3\" tag=\"520\">\n"+
"			\t\t\t<default:subfield code=\"a\">" + description.trim() + "</default:subfield>\n"+
"		\t\t</default:datafield>\n"+
"		\t\t<default:datafield ind2=\"0\" tag=\"655\">\n"+
"			\t\t\t<default:subfield code=\"a\">data holding</default:subfield>\n"+
"		\t\t</default:datafield>\n"+
"		\t\t<default:datafield ind2=\"0\" tag=\"655\">\n"+
"			\t\t\t<default:subfield code=\"a\">crystal structure data holding</default:subfield>\n"+
"		\t\t</default:datafield>\n"+                                                      
"		\t\t<default:datafield ind1=\"0\" ind2=\"0\" tag=\"773\">\n"+
"			\t\t\t<default:subfield code=\"t\">" + URLEncoder.encode(relation.trim(), "UTF-8") + "</default:subfield>\n"+
"		\t\t</default:datafield>\n"+
"	\t</default:record>\n"+
"</default:collection>\n"+
					      "");
                                              
                                              xmlDataMARC.getContent().add(preformedMARC);
                                            }
                                            catch(UnsupportedEncodingException e)
                                            {
                                                System.out.println("Unsupported URL encoding for Relation");
                                            }
                                              
					    
					mdWrapMARC.getContent().add(xmlDataMARC);
			techMDMARC.getContent().add(mdWrapMARC);
		amdSecMARC.getContent().add(techMDMARC);
	mets.getContent().add(amdSecMARC);        
        
	FileSec fileSec = new FileSec();
		FileGrp fileGrp = new FileGrp();
		fileGrp.setID("DATASTREAMS");
	fileSec.getContent().add(fileGrp);
	
	mets.getContent().add(fileSec);
	
	// fedora hates structmaps when ingesting...
	/*StructMap structMap = new StructMap();
		structMap.setID("DISS1.0b");
		structMap.setTYPE("fedora:dsBindingMap");
		
			Div div = new Div();
			div.setTYPE("dummy:1");
		
		structMap.getContent().add(div);
	
	mets.getContent().add(structMap);*/
	
	System.out.println("Constructed METS XML object");
		    
	}
	
	private static String[] creatorArray(String creators) {
		return creators.split(",");
	}

	public static String writeMETS(String outputPath, String label, String[] creators, String description,
				String source, String relation)
	{

		try {
			CreateMETSObject(label, creators, description, source, relation);
			mets.validate (new MetsValidator ());
		
			FileOutputStream out = new FileOutputStream (outputPath);
			mets.write (new MetsWriter (out), true);

			out.close ();
			
			System.out.println("Wrote to " + outputPath);
		
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return outputPath;
	}
	
	public static void main(String[] args)
	{		
		
		if(args.length == 6)
		{
			
			MetsCreator.writeMETS(args[0], args[1], creatorArray(args[2]), args[3], args[4], args[5]);
			
		}
		else
		{
			System.out.println("MetsCreator by Steve Androulakis - For creating Fedora-compatible METS XML data for object ingestion");
			System.out.println("");
			System.out.println("USAGE:");
			System.out.println("MetsCreator <outputPath> <objectName>");
			System.out.println("\t<creatorName,creatorName2...> <objectDescription> <sourceURL> <relationURL>");
			System.out.println("\nNote: For arguments with spaces in it, such as the description, wrap quotes around the argument");
			System.out.println("");
			System.out.println("EXAMPLE:");
			System.out.println("MetsCreator /Users/steve/Desktop/mets2.xml \"My Test Object 2.0\"\n\t \"Steve, Bill, Joe\" \"A description\" http://www.google.com.au http://www.relation.com");
			System.out.println("");
			System.out.println("outputPath: The absolute path for the generated METS xml file");
			System.out.println("creatorName: Comma separated creator names for the object (Fedora DublinCore data)");
			System.out.println("objectDescription: Description of the object (Fedora DublinCore data)");
			System.out.println("sourceURL: The source URL (Fedora DublinCore data)");
			System.out.println("relationURL: The relation URL (Fedora DublinCore data)");
		}		

		
		//String outputPath = "/Users/steve/Desktop/mets.xml";
		//String[] creators = { "Steve Androulakis", "Billy Bob", "Jeth Ro" };
		
		//new MetsCreator("testme:50", "My Test Object 2.0", creators, "A description", "http://www.google.com.au", "http://www.relation.com").writeMETS(outputPath);
	}
	
}